using SPI.AgentServer.Services.Execution;
using SPI.AgentServer.Services.AI;
using System.Net.Sockets;
using System.Diagnostics;

namespace SPI.AgentServer.Services.Infrastructure;

/// <summary>
/// 增强的连接保活服务 - 定期检查数据库、AI服务和Kestrel健康状态，防止空闲超时
/// </summary>
public class ConnectionKeepAliveService : BackgroundService
{
    private readonly IServiceProvider _serviceProvider;
    private readonly ILogger<ConnectionKeepAliveService> _logger;
    private readonly IConfiguration _configuration;
    private readonly TimeSpan _checkInterval = TimeSpan.FromSeconds(90); // 每90秒检查一次（平衡频率和性能）
    private readonly TimeSpan _initialDelay = TimeSpan.FromSeconds(30); // 启动后30秒开始第一次检查
    
    private int _consecutiveFailures = 0;
    private const int MaxConsecutiveFailures = 3;
    
    private DateTime _lastSuccessfulCheck = DateTime.UtcNow;
    private DateTime _serviceStartTime = DateTime.UtcNow;

    public ConnectionKeepAliveService(
        IServiceProvider serviceProvider,
        ILogger<ConnectionKeepAliveService> logger,
        IConfiguration configuration)
    {
        _serviceProvider = serviceProvider;
        _logger = logger;
        _configuration = configuration;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _serviceStartTime = DateTime.UtcNow;
        _logger.LogInformation("🔄 增强连接保活服务已启动");
        _logger.LogInformation("   ├─ 检查间隔：{Interval}分钟", _checkInterval.TotalMinutes);
        _logger.LogInformation("   ├─ 初始延迟：{Delay}秒", _initialDelay.TotalSeconds);
        _logger.LogInformation("   └─ 监控范围：数据库 + AI服务 + Kestrel自检");

        // 等待初始延迟后开始第一次检查
        await Task.Delay(_initialDelay, stoppingToken);

        while (!stoppingToken.IsCancellationRequested)
        {
            var checkStartTime = DateTime.UtcNow;
            
            try
            {
                await PerformComprehensiveHealthCheckAsync(stoppingToken);
                
                _consecutiveFailures = 0; // 重置失败计数
                _lastSuccessfulCheck = DateTime.UtcNow;
                
                var checkDuration = (DateTime.UtcNow - checkStartTime).TotalMilliseconds;
                _logger.LogInformation("✅ 健康检查完成 (耗时: {Duration}ms, 运行时长: {Uptime})", 
                    (int)checkDuration,
                    FormatUptime(DateTime.UtcNow - _serviceStartTime));
                
                await Task.Delay(_checkInterval, stoppingToken);
            }
            catch (OperationCanceledException)
            {
                _logger.LogInformation("连接保活服务正在停止");
                break;
            }
            catch (Exception ex)
            {
                _consecutiveFailures++;
                
                _logger.LogError(ex, "❌ 健康检查失败 (连续失败次数: {Count}/{Max})", 
                    _consecutiveFailures, MaxConsecutiveFailures);
                
                if (_consecutiveFailures >= MaxConsecutiveFailures)
                {
                    _logger.LogCritical("🚨 严重警告：连续 {Count} 次健康检查失败！服务可能存在问题", _consecutiveFailures);
                }
                
                // 出错后等待较短时间再重试
                await Task.Delay(TimeSpan.FromSeconds(30), stoppingToken);
            }
        }
    }

    private async Task PerformComprehensiveHealthCheckAsync(CancellationToken cancellationToken)
    {
        var stopwatch = Stopwatch.StartNew();
        
        _logger.LogDebug("🔍 开始综合健康检查...");

        // 使用作用域服务
        using var scope = _serviceProvider.CreateScope();
        
        // 1. 检查数据库连接
        await CheckDatabaseHealthAsync(scope, cancellationToken);
        
        // 2. 检查AI服务连接
        await CheckAIServiceHealthAsync(scope, cancellationToken);
        
        // 3. 检查Kestrel自身健康状态
        await CheckKestrelHealthAsync(cancellationToken);
        
        stopwatch.Stop();
        _logger.LogDebug("   └─ 检查完成，总耗时: {Duration}ms", stopwatch.ElapsedMilliseconds);
    }

    private async Task CheckDatabaseHealthAsync(IServiceScope scope, CancellationToken cancellationToken)
    {
        try
        {
            var dbExecutor = scope.ServiceProvider.GetRequiredService<IDatabaseExecutor>();
            var stopwatch = Stopwatch.StartNew();
            
            var testResult = await dbExecutor.TestConnectionAsync("Test", cancellationToken);
            stopwatch.Stop();
            
            if (testResult)
            {
                _logger.LogDebug("   ├─ 数据库连接: ✅ 正常 ({Duration}ms)", stopwatch.ElapsedMilliseconds);
            }
            else
            {
                _logger.LogWarning("   ├─ 数据库连接: ⚠️ 测试失败");
            }
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "   ├─ 数据库连接: ❌ 异常");
            throw; // 重新抛出以增加失败计数
        }
    }

    private async Task CheckAIServiceHealthAsync(IServiceScope scope, CancellationToken cancellationToken)
    {
        try
        {
            var useMock = _configuration.GetValue<bool>("Qwen:UseMock");
            if (useMock)
            {
                _logger.LogDebug("   ├─ AI服务: ✅ Mock模式，跳过检查");
                return;
            }

            var baseUrl = _configuration["Qwen:BaseUrl"] ?? "";
            if (string.IsNullOrEmpty(baseUrl))
            {
                _logger.LogDebug("   ├─ AI服务: ⚠️ 未配置BaseUrl");
                return;
            }

            var uri = new Uri(baseUrl);
            var stopwatch = Stopwatch.StartNew();
            
            // TCP连接测试
            using var client = new TcpClient();
            var connectTask = client.ConnectAsync(uri.Host, uri.Port);
            var timeoutTask = Task.Delay(TimeSpan.FromSeconds(3), cancellationToken);
            
            var completedTask = await Task.WhenAny(connectTask, timeoutTask);
            stopwatch.Stop();
            
            if (completedTask == connectTask && client.Connected)
            {
                _logger.LogDebug("   ├─ AI服务 ({Endpoint}): ✅ 可达 ({Duration}ms)", 
                    $"{uri.Host}:{uri.Port}", stopwatch.ElapsedMilliseconds);
            }
            else
            {
                _logger.LogWarning("   ├─ AI服务 ({Endpoint}): ⚠️ 连接超时 ({Duration}ms)", 
                    $"{uri.Host}:{uri.Port}", stopwatch.ElapsedMilliseconds);
            }
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "   ├─ AI服务: ❌ 检查异常");
            // AI服务失败不中断整个健康检查
        }
    }

    private async Task CheckKestrelHealthAsync(CancellationToken cancellationToken)
    {
        try
        {
            // 【关键修复】不只是检查端口，而是真正发送HTTP请求！
            // 这样可以：
            // 1. 唤醒Kestrel的HTTP监听器
            // 2. 防止Windows网络空闲超时
            // 3. 保持完整的请求处理管道活跃
            
            var stopwatch = Stopwatch.StartNew();
            
            // 创建HttpClient发送真实的HTTP请求
            using var httpClient = new HttpClient();
            httpClient.Timeout = TimeSpan.FromSeconds(5);
            
            try
            {
                // 发送真实的健康检查请求
                var response = await httpClient.GetAsync("http://127.0.0.1:8215/api/health/alive", cancellationToken);
                stopwatch.Stop();
                
                if (response.IsSuccessStatusCode)
                {
                    _logger.LogDebug("   ├─ Kestrel HTTP: ✅ 正常响应 ({Duration}ms)", 
                        stopwatch.ElapsedMilliseconds);
                }
                else
                {
                    _logger.LogWarning("   ├─ Kestrel HTTP: ⚠️ 状态码异常 {StatusCode} ({Duration}ms)", 
                        (int)response.StatusCode, stopwatch.ElapsedMilliseconds);
                }
            }
            catch (TaskCanceledException)
            {
                stopwatch.Stop();
                _logger.LogCritical("   ├─ Kestrel HTTP: 🚨 请求超时 ({Duration}ms)！", 
                    stopwatch.ElapsedMilliseconds);
                throw new InvalidOperationException("Kestrel HTTP请求超时");
            }
            catch (HttpRequestException ex)
            {
                stopwatch.Stop();
                _logger.LogCritical(ex, "   ├─ Kestrel HTTP: 🚨 无法连接 ({Duration}ms)！", 
                    stopwatch.ElapsedMilliseconds);
                throw; // 重新抛出以增加失败计数
            }
        }
        catch (Exception ex)
        {
            _logger.LogCritical(ex, "   ├─ Kestrel健康检查: 🚨 严重错误");
            throw; // 重新抛出以增加失败计数
        }
    }

    private string FormatUptime(TimeSpan uptime)
    {
        if (uptime.TotalDays >= 1)
            return $"{(int)uptime.TotalDays}天{uptime.Hours}小时";
        if (uptime.TotalHours >= 1)
            return $"{(int)uptime.TotalHours}小时{uptime.Minutes}分钟";
        if (uptime.TotalMinutes >= 1)
            return $"{(int)uptime.TotalMinutes}分钟";
        return $"{(int)uptime.TotalSeconds}秒";
    }

    public override async Task StopAsync(CancellationToken cancellationToken)
    {
        var totalUptime = DateTime.UtcNow - _serviceStartTime;
        _logger.LogInformation("🛑 连接保活服务正在停止 (总运行时长: {Uptime})", FormatUptime(totalUptime));
        await base.StopAsync(cancellationToken);
    }
}
